﻿using Microsoft.Extensions.DependencyInjection;
using Niaofei.Application.Contracts;
using Niaofei.Domain;
using Niaofei.Injcetion;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Niaofei.Application
{
    [Injection(typeof(ISysMenuAppService))]
    internal class SysMenuAppService : NiaofeiAppService, ISysMenuAppService
    {
        private readonly ISysMenuRepository _sysMenuRepository;

        public SysMenuAppService(IServiceProvider serviceProvider) : base(serviceProvider)
        {
            _sysMenuRepository = serviceProvider.GetRequiredService<ISysMenuRepository>();
        }

        public async Task<ResultDto<SysMenuDto>> Add(SysMenuDto input)
        {
            var entity = Mapper.Map<SysMenuDto, SysMenu>(input);

            entity = await _sysMenuRepository.InsertAsync(entity);

            var result = Mapper.Map<SysMenu, SysMenuDto>(entity);

            return new ResultDto<SysMenuDto>(result);
        }

        public async Task<ResultDto<string>> Remove(List<int> ids)
        {
            var entitys = (await _sysMenuRepository.GetQueryableAsync())
                .Where(m => ids.Contains(m.Id))
                .ToList();

            await _sysMenuRepository.DeleteManyAsync(entitys);

            return new ResultDto<string>() { Code = "0", Data = "删除成功" };
        }

        public async Task<ResultDto<SysMenuDto>> Update(SysMenuDto input)
        {
            var entity = (await _sysMenuRepository.GetQueryableAsync())
                .FirstOrDefault(m => m.Id == input.Id);

            Mapper.Map(input, entity);

            entity = await _sysMenuRepository.UpdateAsync(entity);

            var result = Mapper.Map<SysMenu, SysMenuDto>(entity);

            return new ResultDto<SysMenuDto>(result);
        }

        public async Task<ResultDto<List<SysMenuOutputDto>>> GetTreeNodes(SysMenuInputDto input)
        {
            var query = (await _sysMenuRepository.GetQueryableAsync())
                .WhereIf(!input.IsVisible, m => m.Visible);

            var entitys = query.ToList();

            var nodes = Mapper.Map<List<SysMenu>, List<SysMenuOutputDto>>(entitys);

            var result = nodes.OrderBy(m => m.Sort).Where(m => m.ParentId == null).ToList();

            result.ForEach(m => m.SetChildren(nodes));

            return new ResultDto<List<SysMenuOutputDto>>(result);
        }

        public async Task<ResultDto<List<SysMenuOutputDto>>> GetMenuPath(int id)
        {
            var query = (await _sysMenuRepository.GetQueryableAsync())
               .Where(m => m.Visible);

            var entitys = query.ToList();

            var nodes = Mapper.Map<List<SysMenu>, List<SysMenuOutputDto>>(entitys);

            var node = nodes.FirstOrDefault(m => m.Id == id);

            var result = new List<SysMenuOutputDto>();
            while (node != null)
            {
                result.Insert(0, node);
                node = nodes.FirstOrDefault(m => m.Id == node.ParentId && node.ParentId != null);
            }

            return new ResultDto<List<SysMenuOutputDto>>(result);
        }
    }
}
